package com.lucifer.treasure.util;

import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 🗡️ 御剑术统一日志管理器
 * 提供分类清晰、格式规范的日志输出功能
 */
public class SwordAuraLogger {
    
    // 日志等级枚举
    public enum LogLevel {
        DEBUG("🔍", "调试"),
        INFO("ℹ️", "信息"), 
        WARN("⚠️", "警告"),
        ERROR("❌", "错误"),
        SUCCESS("✅", "成功"),
        COMBAT("⚔️", "战斗"),
        SYSTEM("🔧", "系统"),
        STATS("📊", "统计"),
        EFFECT("✨", "效果"),
        CACHE("💾", "缓存");
        
        public final String icon;
        public final String name;
        
        LogLevel(String icon, String name) {
            this.icon = icon;
            this.name = name;
        }
    }
    
    // 日志分类枚举
    public enum Category {
        INIT("初始化", "🔄"),
        SWORD_MANAGEMENT("剑管理", "🗡️"),
        ATTACK("攻击", "⚔️"),
        TARGET("目标", "🎯"),
        DAMAGE("伤害", "💥"),
        ENCHANT("附魔", "✨"),
        CACHE("缓存", "💾"),
        PLAYER("玩家", "👤"),
        ENTITY("实体", "🧟"),
        POSITION("位置", "📍"),
        STATS("统计", "📊"),
        TOGGLE("切换", "🔀"),
        CLEANUP("清理", "🧹");
        
        public final String name;
        public final String icon;
        
        Category(String name, String icon) {
            this.name = name;
            this.icon = icon;
        }
    }
    
    // 防刷屏机制
    private static final Map<String, Long> LAST_LOG_TIME = new HashMap<>();
    private static final Map<String, Integer> LOG_COUNT = new HashMap<>();
    private static final long SPAM_THRESHOLD = 1000; // 1秒防刷屏
    private static final int MAX_REPEATED_LOGS = 3;   // 最多重复3次
    
    // 日志开关
    private static boolean DEBUG_ENABLED = false;      // 调试日志默认关闭
    private static boolean COMBAT_LOGS_ENABLED = true;
    private static boolean CACHE_LOGS_ENABLED = false; // 缓存日志默认关闭
    private static boolean STATS_LOGS_ENABLED = true;
    
    /**
     * 通用日志输出方法
     */
    public static void log(LogLevel level, Category category, String message) {
        // 检查日志开关
        if (!isLogEnabled(level, category)) {
            return;
        }
        
        String logKey = category.name + ":" + message;
        long currentTime = System.currentTimeMillis();
        
        // 防刷屏检查
        if (shouldSuppressLog(logKey, currentTime)) {
            return;
        }
        
        // 格式化输出
        String formattedMessage = formatLogMessage(level, category, message);
        System.out.println(formattedMessage);
        
        // 更新防刷屏记录
        updateSpamRecord(logKey, currentTime);
    }
    
    /**
     * 快捷方法 - 剑管理日志
     */
    public static void swordManagement(String playerName, String action, int swordCount, int maxSwords) {
        String message = String.format("[%s] %s - 当前:%d把剑 最大:%d把", 
            playerName, action, swordCount, maxSwords);
        log(LogLevel.INFO, Category.SWORD_MANAGEMENT, message);
    }
    
    /**
     * 快捷方法 - 剑数量变化日志（特殊防刷屏）
     */
    public static void swordCountChange(String playerName, int oldCount, int newCount, String reason) {
        String message = String.format("[%s] 剑数量变化: %d → %d (%s)", 
            playerName, oldCount, newCount, reason);
        
        // 特殊的防刷屏机制 - 剑数量变化日志5秒内只能输出一次
        String specialKey = "SWORD_COUNT_" + playerName;
        long currentTime = System.currentTimeMillis();
        Long lastTime = LAST_LOG_TIME.get(specialKey);
        
        if (lastTime == null || (currentTime - lastTime) > 5000) { // 5秒间隔
            log(LogLevel.INFO, Category.SWORD_MANAGEMENT, message);
            LAST_LOG_TIME.put(specialKey, currentTime);
        }
    }
    
    /**
     * 快捷方法 - 初始化日志
     */
    public static void initialization(String playerName, String action) {
        String message = String.format("[%s] %s", playerName, action);
        log(LogLevel.INFO, Category.INIT, message);
    }
    
    /**
     * 快捷方法 - 攻击日志
     */
    public static void attack(String playerName, int swordIndex, String targetName, boolean hit, String damage) {
        String result = hit ? "击中" : "未击中";
        String message = String.format("[%s] 剑%d %s %s %s", 
            playerName, swordIndex, result, targetName, damage != null ? "造成" + damage + "点伤害" : "");
        log(LogLevel.COMBAT, Category.ATTACK, message);
    }
    
    /**
     * 快捷方法 - 目标检测日志（防刷屏）
     */
    public static void targetDetection(String playerName, int targetCount, String primaryTarget) {
        String message = String.format("[%s] 检测到 %d 个目标", playerName, targetCount);
        if (primaryTarget != null && !primaryTarget.isEmpty()) {
            message += " - 主要威胁: " + primaryTarget;
        }
        
        // 目标检测日志2秒内只能输出一次，且目标数量必须有变化
        String specialKey = "TARGET_DETECTION_" + playerName + "_" + targetCount;
        long currentTime = System.currentTimeMillis();
        Long lastTime = LAST_LOG_TIME.get(specialKey);
        
        if (lastTime == null || (currentTime - lastTime) > 2000) { // 2秒间隔
            log(LogLevel.DEBUG, Category.TARGET, message);
            LAST_LOG_TIME.put(specialKey, currentTime);
        }
    }
    
    /**
     * 快捷方法 - 统计日志
     */
    public static void stats(String playerName, int swordIndex, String targetName, int hitCount, int totalCount) {
        double hitRate = totalCount > 0 ? (hitCount * 100.0 / totalCount) : 0.0;
        String message = String.format("[%s] 剑%d 击中 %s | 命中率: %d/%d (%.1f%%)", 
            playerName, swordIndex, targetName, hitCount, totalCount, hitRate);
        log(LogLevel.STATS, Category.STATS, message);
    }
    
    /**
     * 快捷方法 - 批量攻击日志
     */
    public static void batchAttack(String playerName, int targetCount) {
        String message = String.format("[%s] 批量攻击 %d 个目标", playerName, targetCount);
        log(LogLevel.COMBAT, Category.ATTACK, message);
    }
    
    /**
     * 快捷方法 - 附魔效果日志
     */
    public static void enchantEffect(String enchantName, int level, String effect) {
        String message = String.format("%s %d 级%s: %s", enchantName, level, level > 1 ? "加成" : "", effect);
        log(LogLevel.EFFECT, Category.ENCHANT, message);
    }
    
    /**
     * 快捷方法 - 缓存更新日志
     */
    public static void cacheUpdate(String playerName, String action, int count) {
        String message = String.format("[%s] %s", playerName, action);
        if (count >= 0) {
            message += " " + count + " 个目标";
        }
        log(LogLevel.DEBUG, Category.CACHE, message);
    }
    
    /**
     * 快捷方法 - 御剑术状态切换日志
     */
    public static void toggleAura(String playerName, boolean enabled, int auraLevel) {
        String status = enabled ? "开启" : "关闭";
        String message = String.format("[%s] 御剑术%s (等级:%d)", playerName, status, auraLevel);
        log(LogLevel.INFO, Category.TOGGLE, message);
    }
    
    /**
     * 快捷方法 - 清理日志
     */
    public static void cleanup(String action, int count) {
        String message = String.format("%s", action);
        if (count > 0) {
            message += " (" + count + " 项)";
        }
        log(LogLevel.INFO, Category.CLEANUP, message);
    }
    
    /**
     * 快捷方法 - 错误日志
     */
    public static void error(String context, String error) {
        String message = String.format("[%s] %s", context, error);
        log(LogLevel.ERROR, Category.INIT, message);
    }
    
    /**
     * 检查是否应该输出日志
     */
    private static boolean isLogEnabled(LogLevel level, Category category) {
        switch (level) {
            case DEBUG:
                return DEBUG_ENABLED;
            case COMBAT:
                return COMBAT_LOGS_ENABLED;
            case STATS:
                return STATS_LOGS_ENABLED;
            default:
                break;
        }
        
        switch (category) {
            case CACHE:
                return CACHE_LOGS_ENABLED;
            default:
                return true;
        }
    }
    
    /**
     * 检查是否应该抑制日志（防刷屏）
     */
    private static boolean shouldSuppressLog(String logKey, long currentTime) {
        Long lastTime = LAST_LOG_TIME.get(logKey);
        Integer count = LOG_COUNT.get(logKey);
        
        if (lastTime == null) {
            return false; // 第一次记录
        }
        
        if (currentTime - lastTime > SPAM_THRESHOLD) {
            LOG_COUNT.put(logKey, 0); // 重置计数
            return false;
        }
        
        return count != null && count >= MAX_REPEATED_LOGS;
    }
    
    /**
     * 更新防刷屏记录
     */
    private static void updateSpamRecord(String logKey, long currentTime) {
        LAST_LOG_TIME.put(logKey, currentTime);
        LOG_COUNT.put(logKey, LOG_COUNT.getOrDefault(logKey, 0) + 1);
    }
    
    /**
     * 格式化日志消息
     */
    private static String formatLogMessage(LogLevel level, Category category, String message) {
        return String.format("%s [%s%s] %s", 
            level.icon, 
            category.icon, 
            category.name, 
            message);
    }
    
    /**
     * 设置日志开关
     */
    public static void setDebugEnabled(boolean enabled) {
        DEBUG_ENABLED = enabled;
    }
    
    public static void setCombatLogsEnabled(boolean enabled) {
        COMBAT_LOGS_ENABLED = enabled;
    }
    
    public static void setCacheLogsEnabled(boolean enabled) {
        CACHE_LOGS_ENABLED = enabled;
    }
    
    public static void setStatsLogsEnabled(boolean enabled) {
        STATS_LOGS_ENABLED = enabled;
    }
    
    /**
     * 获取玩家名称
     */
    public static String getPlayerName(PlayerEntity player) {
        return player != null ? player.getName().getString() : "未知玩家";
    }
    
    /**
     * 获取实体名称
     */
    public static String getEntityName(LivingEntity entity) {
        return entity != null ? entity.getName().getString() : "未知实体";
    }
    
    /**
     * 获取物品名称
     */
    public static String getItemName(ItemStack stack) {
        return stack != null && !stack.isEmpty() ? stack.getName().getString() : "空物品";
    }
    
    /**
     * 清理过期的防刷屏记录
     */
    public static void cleanupSpamRecords() {
        long currentTime = System.currentTimeMillis();
        LAST_LOG_TIME.entrySet().removeIf(entry -> 
            currentTime - entry.getValue() > SPAM_THRESHOLD * 10);
        LOG_COUNT.entrySet().removeIf(entry -> 
            !LAST_LOG_TIME.containsKey(entry.getKey()));
    }
} 